---
id: register-factory
title: Registering Factories
sidebar_label: Factories
---

VContainer generally constructs registered dependencies the first time they're resolved (except for [registered instances](./register-type#register-instance)). If you need finer control over when a dependency is created, you can register and use a factory function.

Factory functions are [`Func<>`](https://docs.microsoft.com/en-us/dotnet/api/system.func-1) delegates that are resolved like any other dependency. They can be used to create one or more other dependencies at any time.

:::note
Despite what the name "factory" might suggest, factories can return existing objects instead of creating new ones. This can be useful for mapping multiple dependencies of the same type to different keys, such as a unique controller service for each player in a local multiplayer game.
:::

In the following example, dependency resolution will happen only once. Dependency resolution will not occur in this particular `Create()` method (that's what the constructor is for), although you can explicitly use the [`IObjectResolver` API](../resolving/container-api) within a factory if you'd like.


```csharp
class FooFactory
{
    public FooFactory(DependencyA dependencyA)
    {
        this.dependencyA = dependencyA;
    }

    public Foo Create(int b) => new Foo(b, dependencyA);
}
```

```csharp
builder.Register<FooFactory>(Lifetime.Singleton); // Registered

// ...

var factory = container.Resolve<FooFactory>(); // Dependency resolution occurs

// ...

var foo1 = factory.Create(1); // No resolution needed here
var foo2 = factory.Create(2); // No resolution needed here
var foo3 = factory.Create(3); // No resolution needed here
```

Although it's useful to create a factory class as above, simple factories can be registered as [lambda expressions](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/operators/lambda-expressions) as well.

:::caution
VContainer does not automatically manage the lifetime of objects returned by factories. If your factory returns disposable objects, you will need to clean them up yourself. This is an ideal case for a factory class, because the factory itself will be managed by VContainer and will therefore be cleaned up if it implements [`IDisposable`](https://docs.microsoft.com/en-us/dotnet/api/system.idisposable).
:::

## Register `Func<>` Factory that requires only runtime parameters

If your factory doesn't need other dependencies, you can register it like so:

```csharp
builder.RegisterFactory<int, Foo>(x => new Foo(x));
```

Here's how you use it:

```csharp
class ClassA
{
    readonly Func<int, Foo> factory;

    public ClassA(Func<int, Foo> factory)
    {
        this.factory = factory;
    }

    public void DoSomething()
    {
        var foo = factory(100);
        // ...
    }
}
```

## Register `Func<>` Factory that requires container dependencies and runtime parameters

If your factory method *does* need other dependencies, you'll need to provide it with an `IObjectResolver`. You can do so by registering a `Func<>` that accepts an `IObjectResolver` and returns the `Func<>` that you actually want to use.

```csharp
builder.RegisterFactory<int, Foo>(container => // container is an IObjectResolver
{
    var dependency = container.Resolve<Dependency>(); // Resolve per scope
    return x => new Foo(x, dependency); // Execute per factory invocation
}, Lifetime.Scoped);
```

This version requires a [`Lifetime`](../scoping/lifetime-overview) that specifies how often the inner `Func<>` is generated, i.e. how often the outer `Func<>` is called.

Factories with dependencies are resolved in exactly the same way, as shown below.

```csharp
class ClassA
{
    readonly Func<int, Foo> factory;

    public ClassA(Func<int, Foo> factory)
    {
        this.factory = factory;
    }

    public void DoSomething()
    {
        var foo = factory.Invoke(100);
        // ...
    }
}
```

You might find `IObjectResolver`'s various extension methods useful within a factory.

```csharp
builder.RegisterFactory<CharacterType, CharacterActor>(container =>
{
    return characterType =>
    {
        var characterPrefab = ...
        return container.Instantiate(characterPrefab, parentTransform);
    }
}, Lifetime.Scoped);
```

See the [Container API page](../resolving/container-api) for more information.

:::note
Using a lambda function for a `Func<>` registration is shorthand for a common case. In complex scenarios, consider defining and registering your own factory class.
:::

## Registering factory methods

Factories can be registered as any delegate that can be converted to a `Func<>`, including methods. This way, all factories can be used as `Func<>`s no matter how complicated the underlying implementation is. Here's how you would do that.

Suppose we have this class...

```csharp
class FooFactory
{
    public FooFactory(DependencyA dependencyA)
    {
        this.dependencyA = dependencyA;
    }

    public Foo Create(int b) => new Foo(b, dependencyA);
}
```

Here's how you can use `FooFactory` as a `Func<>` without knowing or caring about the full class.

```csharp
builder.Register<FooFactory>(Lifetime.Singleton);
builder.RegisterFactory(container => container.Resolve<FooFactory>().Create, Lifetime.Singleton);

// ...

var factory = container.Resolve<Func<int, Foo>>();

var foo1 = factory(1);
var foo2 = factory(2);
var foo3 = factory(3);

var originalFactoryObject = container.Resolve<FooFactory>(); // The factory object is there if you need it.
// If FooFactory implements IDisposable, it'll be called when the IObjectResolver is disposed.
```
